﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CopySniffer.UI.Views;
using System.IO;
using CopySniffer.Common;
using CopySniffer.UI.Core.Properties;
using System.Security;
using CopySniffer.Search;
using CopySniffer.Search.Boss;
using System.Xml;
using System.Runtime.Serialization;
using System.ComponentModel;
using CopySniffer.FileLoad;
using System.Xml.Xsl;
using System.Resources;
using System.Reflection;

namespace CopySniffer.UI.Core.Controlers
{
    public class EditorControler : BaseControler<IEditorView, EditorControler>
    {
        private string baseViewName;

        public bool Start(MainControler mainControler, string fileName)
        {
            Guard.IsNotNull(mainControler, "mainControler");
            Guard.IsNotNullOrEmpty(fileName, "fileName");
            if (File.Exists(fileName))
            {
                try
                {
                    IFileLoader loader = FileLoaders.GetFileLoader(fileName);
                    baseViewName = Path.GetFileName(fileName);
                    View.UserText = loader.LoadFile(fileName);
                    RefreshWindowName();
                    return true;
                }
                catch (Exception exc)
                {
                    string format = null;
                    if (exc is IOException)
                    {
                        format = Resources.FileOpenError;
                    }
                    else if (exc is SecurityException)
                    {
                        format = Resources.MissingPermissionsError;
                    }
                    else if (exc is UnauthorizedAccessException)
                    {
                        format = Resources.UnauthorizedError;
                    }
                    else
                    {
                        throw;
                    }

                    View.ShowException(format, exc);
                }
            }
            else
            {
                View.ShowError(
                    String.Format(Resources.CouldNotLocateFile, fileName));
            }
            return false;
        }

        public bool Start(MainControler mainController, int editorCount)
        {
            baseViewName = String.Format(
                Resources.NewFileNameFormat, 
                editorCount + 1);
            RefreshWindowName();
            return true;
        }

        private void RefreshWindowName()
        {
            if (View.State == EditorState.Modified)
            {
                View.ViewTitle = String.Format(
                        Resources.ModifiedFileNameFormat, 
                        baseViewName);
            }
            else
            {
                View.ViewTitle = baseViewName;
            }
        }

        public void Cut()
        {
            View.Cut();
        }

        public void Copy()
        {
            View.Copy();
        }

        public void Paste()
        {
            View.Paste();
        }


        public void TreatTextChange()
        {
            if (View.State != EditorState.Modified)
            {
                View.State = EditorState.Modified;
                View.ViewTitle = String.Format(
                        Resources.ModifiedFileNameFormat, 
                        baseViewName);
            }
        }

        public void SearchCopies()
        {
            try
            {
                View.BeginWaitState();
                // TODO: inject this dependency later on
                BossCopySearcher copySearcher = new BossCopySearcher();
                copySearcher.SearchAsync(View.UserText, 3, SearcherFinished);
            }
            catch
            {
                View.EndWaitState();
            }
        }

        public void SearcherFinished(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                var results = (IEnumerable<PairedSearchResults>)e.Result;
                results = results.OrderByDescending(p => p.Results != null ? p.Results.Count() : 0).ToList();
                StringBuilder sb = new StringBuilder();
                XmlWriter writer = XmlWriter.Create(sb, new XmlWriterSettings() { Encoding = Encoding.UTF8, Indent = true });
                DataContractSerializer serializer = new DataContractSerializer(results.GetType());
                writer.WriteProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"Results.xslt\"");
                serializer.WriteObject(writer, results);
                writer.Close();
                XmlDocument resultsXml = new XmlDocument();
                resultsXml.LoadXml(sb.ToString());
                View.ShowResults(resultsXml);
            }
            finally
            {
                View.EndWaitState();
            }
        }


        public XslCompiledTransform GetResultsXslt()
        {
            XslCompiledTransform xslt = new XslCompiledTransform();
            XsltArgumentList args = new XsltArgumentList();
            ResourceManager rm = new ResourceManager("CopySniffer.UI.Core", Assembly.GetExecutingAssembly());
            using (XmlReader reader = XmlReader.Create(
                Assembly.GetExecutingAssembly().GetManifestResourceStream(
                    "CopySniffer.UI.Core.Results.xslt")))
            {

                xslt.Load(reader);
            }
            return xslt;
        }
    }
}
